//File: Mergesort.java //A Java application to illustrate the use of a merge sort //Additional javadoc documentation is available at: //http://www.cs.colorado.edu/~main/docs/Mergesort.html /******************************************************************************* * The <CODE>Mergesort</CODE> Java application illustrates a merge sort. * * <p> * <dt><b>Java Source Code for this class: </b> * <dd><A HREF="http://www.cs.colorado.edu/~main/applications/Mergesort.java"> * http://www.cs.colorado.edu/~main/applications/Mergesort.java </A> * * @author Michael Main <A HREF="mailto:main@colorado.edu"> (main@colorado.edu) * </A> * * @version Jun 12, 1998 ******************************************************************************/ public class MergeSort { /** * The main method illustrates the use of a merge sort to sort a small * array. The <CODE>String</CODE> arguments (<CODE>args</CODE>) are * not used in this implementation. */ public static void main(String[] args) { final String BLANKS = " "; // A String of two blanks int i; // Array index String[] data = {"Shahein", "Abena", "Ryan", "John"}; // Print the array before sorting: System.out.println("Here is the entire original array:"); for (i = 0; i < data.length; i++) System.out.print(data[i] + BLANKS); System.out.println(); // Sort the numbers, and print the result with two blanks after each // number. mergesort(data, 0, data.length ); System.out.println("I have sorted all the strings."); System.out.println("The strings are:"); for (i = 0; i < data.length; i++) System.out.print(data[i] + BLANKS); System.out.println(); } /** * Sort an array of integers from smallest to largest, using a merge sort * algorithm. * * @param <CODE> * data</CODE> the array to be sorted * @param <CODE> * first</CODE> the start index for the portion of the array * that will be sorted * @param <CODE> * n</CODE> the number of elements to sort * <dt><b>Precondition: </b> * <dd><CODE>data[first]</CODE> through <CODE>data[first+n-1] * </CODE> are valid parts of the array. * <dt><b>Postcondition: </b> * <dd>If <CODE>n</CODE> is zero or negative then no work is * done. Otherwise, the elements of</CODE> data</CODE> have * been rearranged so that <CODE>data[first] <= data[first+1] * <= ... <= data[first+n-1]</CODE>. * @exception ArrayIndexOutOfBoundsException * Indicates that <CODE>first+n-1</CODE> is an index beyond * the end of the array. */ public static void mergesort(String[] data, int first, int n) { int n1; // Size of the first half of the array int n2; // Size of the second half of the array if (n > 1) { // Compute sizes of the two halves n1 = n / 2; n2 = n - n1; mergesort(data, first, n1); // Sort data[first] through // data[first+n1-1] mergesort(data, first + n1, n2); // Sort data[first+n1] to the end // Merge the two sorted halves. merge(data, first, n1, n2); } } private static void merge(String[] data, int first, int n1, int n2) // Precondition: data has at least n1 + n2 components starting at // data[first]. The first // n1 elements (from data[first] to data[first + n1 � 1] are sorted from // smallest // to largest, and the last n2 (from data[first + n1] to data[first + n1 + // n2 - 1]) are also // sorted from smallest to largest. // Postcondition: Starting at data[first], n1 + n2 elements of data // have been rearranged to be sorted from smallest to largest. // Note: An OutOfMemoryError can be thrown if there is insufficient // memory for an array of n1+n2 ints. { String[] temp = new String[n1 + n2]; // Allocate the temporary array int copied = 0; // Number of elements copied from data to temp int copied1 = 0; // Number copied from the first half of data int copied2 = 0; // Number copied from the second half of data int i; // Array index to copy from temp back into data // Merge elements, copying from two halves of data to the temporary // array. while ((copied1 < n1) && (copied2 < n2)) { boolean before = false, after = false, equal = false; if (data[first + copied1].compareTo(data[first + n1 + copied2]) > 0) after = true; else if (data[first + copied1].compareTo(data[first + n1 + copied2]) < 0) before = true; else equal = true; //if (data[first + copied1] < data[first + n1 + copied2]) if (before) temp[copied++] = data[first + (copied1++)]; else temp[copied++] = data[first + n1 + (copied2++)]; } // Copy any remaining entries in the left and right subarrays. while (copied1 < n1) temp[copied++] = data[first + (copied1++)]; while (copied2 < n2) temp[copied++] = data[first + n1 + (copied2++)]; // Copy from temp back to the data array. for (i = 0; i < n1 + n2; i++) data[first + i] = temp[i]; } }